// 基于element-plus的视图组件
window.joEl = {};

// joEl组件
(function () {
    joEl.component = function (app) {
        app.component('jo-el-table', {
            // 可以接受的属性
            props: ['url', 'cols', 'callbacks'],
            data: function () {
                return {
                    tableData: [],
                    page: {
                        pageNumber: 1,
                        pageSize: 10,
                        pageSizes: [10, 20, 50, 100],
                        total: 0,
                        layout: 'total, sizes, prev, pager, next',   //, jumper
                        hideOnSinglePage: false
                    }
                };
            },
            template: `
            <div class="jo-el-table-bar">
                <div class="jo-el-table-data-bar">
                    <slot name="stable" :cols="cols" :data="tableData">
                        <el-table :data="tableData" border header-cell-class-name="jo-el-table-header">
                            <slot>
                                   <el-table-column v-for="col in cols" :type="col.type" :prop="col.field" :label="col.label"
                                    :width="col.width" :header-align="col.headerAlign" :align="col.align" :formatter="col.formatter">
                                    </el-table-column>
                                    <slot name="soper"></slot>
                            </slot>
                        </el-table>
                    </slot>

                </div>
                <div class="jo-el-table-page-bar">
                    <slot name="spage" :page="page">
                          <el-pagination
                            :currentPage="page.pageNumber"
                            :page-sizes="page.pageSizes"
                            :page-size="page.pageSize"
                            :total="page.total"
                            :layout="page.layout"
                            :background="true"
                            :hide-on-single-page="page.hideOnSinglePage"
                            @size-change="handleSizeChange"
                            @current-change="goPage"
                            class=""
                            >
                          </el-pagination>
                    </slot>
                </div>
            </div>
            `,
            methods: {
                // 页大小变更
                handleSizeChange(pageSize) {
                    this.searchInvoke({pageNumber: 1, pageSize: pageSize});
                },
                // 去第n页
                goPage(pageNumber) {
                    if (!pageNumber) {
                        console.info('pageNumber重置为1');
                        pageNumber = 1;
                    }
                    this.searchInvoke({pageNumber: pageNumber});
                },
                // 数据查询执行核心方法
                searchInvoke(extParam) {
                    var _this = this;
                    // 构造查询参数, 包括表单参数和分页参数等
                    var param = _this.buildSearchParam(extParam);
                    jo.postAjax(_this.url, param, function (json) {
                        if (json && json.code === 0) {
                            var list = json.data;
                            for (var i = 0; i < list.length; i++) {
                                var item = list[i];
                                if (_this.callbacks && typeof _this.callbacks.handleItem == 'function') {
                                    _this.callbacks.handleItem(item, i);
                                }
                            }
                            _this.tableData = json.data;
                            _this.page.pageNumber = json.pageNumber;
                            _this.page.pageSize = json.pageSize;
                            _this.page.total = json.total;
                        } else {
                            jo.log('查询数据失败', json);
                        }
                    }, true);
                },
                // 构造查询参数
                buildSearchParam(extParam) {
                    var param;
                    // 用户输入的查询条件
                    if (this.callbacks && typeof this.callbacks.paramBuild == 'function') {
                        param = this.callbacks.paramBuild();
                    }
                    if (!param) {
                        param = {};
                    }
                    // 分页参数
                    param.pageNumber = this.page.pageNumber;
                    param.pageSize = this.page.pageSize;
                    // 指定的扩展参数, 和上面参数重复的, 以扩展参数为准, 可以用来参数校准
                    if (extParam) {
                        param = jo.mergeObject(param, extParam);
                    }
                    // 参数处理钩子
                    if (this.callbacks && typeof this.callbacks.paramHandle == 'function') {
                        this.callbacks.paramHandle(param);
                    }
                    return param;
                }
            },
            mounted() {
                this.goPage(1);
                console.info('[jo-el-table] mounted');
            }
        });

        app.component('jo-el-data', {
            props: ['url'],
            data: function () {
                return {
                    data: []
                };
            },
            template: `<div class="jo-el-data-bar"><slot :data="data" :url="url"></slot></div>`,
            mounted() {
                var _this = this;
                jo.postAjax(this.url, {}, function (json) {
                    if (json && json.code == 0) {
                        _this.data = json.data;
                    }
                }, true);
                console.info('[jo-el-data] mounted, url: ' + this.url);
            }
        });
    };
})();

// joEl方法库
(function () {
    // 当key不存在时赋值
    joEl.putIfNoValue = function (obj, key, value) {
        if (!jo.isValid(key)) {
            console.info('当前key已存在:' + key)
        } else {
            obj[key] = value;
        }
    };

    /**
     * 构造vue参数, 多个参数合并为一个参数, 优先级为入参顺序
     * @param param 定制参数
     * @param commonParam 合并参数
     * @returns {*}
     */
    joEl.buildVueAppParam = function (param, commonParam) {
        if (arguments.length > 2) {
            for (var i = 1; i < arguments.length; i++) {
                var p = arguments[i];
                param = joEl.buildVueAppParamInvoke(param, p, i);
            }
            return param;
        } else if (commonParam) {
            return joEl.buildVueAppParamInvoke(param, commonParam);
        } else {
            return param;
        }
    };

    // 实际执行vue参数合并函数, idx表示序号参数合并序号, 从1开始
    joEl.buildVueAppParamInvoke = function (param, commonParam, idx) {
        // 初始化方法
        if (!param.methods) {
            param.methods = {};
        }
        idx = jo.getDefVal(idx, 1);
        var preData = 'data__backup';
        var preCommonData = 'common__data__backup';
        // 暂存定制data方法
        param.methods[preData + idx] = param.data;
        param.methods[preCommonData + idx] = commonParam.data;
        // 重写data
        param.data = function () {
            var common = typeof this[preCommonData + idx] == 'function' ? this[preCommonData + idx]() : {};
            var data = typeof this[preData + idx] == 'function' ? this[preData + idx]() : {};
            var result = jo.mergeObject(common, data);
            console.debug('当前data的序号为=%s,公共data=%o,基础data=%o,合并后data=%o', idx, common, data, result);
            return result;
        };

        // 初始化计算变量
        if (!param.computed) {
            param.computed = {};
        }
        if (commonParam.computed) {
            for (var k in commonParam.computed) {
                // 不存在则填充计算变量
                joEl.putIfNoValue(param.computed, k, commonParam.computed[k]);
            }
        }

        // 填充方法
        if (commonParam.methods) {
            for (var k in commonParam.methods) {
                // 不存在则填充方法
                joEl.putIfNoValue(param.methods, k, commonParam.methods[k]);
            }
        }

        // mounted
        if (!param.mounted) {
            param.mounted = commonParam.mounted;
        }

        return param;
    };
})();